package com.zenithmind.coding.mapper;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * 问题统计Mapper接口 - 遵循接口隔离原则，专门处理问题统计相关的数据访问
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Mapper
public interface ProblemStatisticsMapper {

    /**
     * 更新问题统计信息
     * 
     * @param problemId 问题ID
     * @param submitCount 提交次数增量
     * @param acceptCount 通过次数增量
     * @return 更新行数
     */
    int updateStatistics(@Param("problemId") String problemId,
                        @Param("submitCount") Long submitCount,
                        @Param("acceptCount") Long acceptCount);

    /**
     * 更新问题平均性能
     * 
     * @param problemId 问题ID
     * @param avgTime 平均用时
     * @param avgMemory 平均内存
     * @return 更新行数
     */
    int updateAvgPerformance(@Param("problemId") String problemId,
                            @Param("avgTime") Integer avgTime,
                            @Param("avgMemory") Integer avgMemory);

    /**
     * 获取问题统计信息
     * 
     * @param categoryId 分类ID
     * @param difficulty 难度等级
     * @return 统计信息
     */
    ProblemStatistics selectProblemStatistics(@Param("categoryId") String categoryId,
                                             @Param("difficulty") Integer difficulty);

    /**
     * 获取热门标签
     * 
     * @param limit 限制数量
     * @return 标签列表
     */
    List<TagStatistics> selectHotTags(@Param("limit") Integer limit);

    /**
     * 获取用户解题统计
     * 
     * @param userId 用户ID
     * @return 解题统计
     */
    UserSolveStatistics selectUserSolveStatistics(@Param("userId") String userId);

    /**
     * 获取难度分布统计
     * 
     * @param categoryId 分类ID
     * @return 难度分布
     */
    List<Object> selectDifficultyDistribution(@Param("categoryId") String categoryId);

    /**
     * 获取类型分布统计
     * 
     * @param categoryId 分类ID
     * @return 类型分布
     */
    List<Object> selectTypeDistribution(@Param("categoryId") String categoryId);

    /**
     * 获取提交趋势数据
     * 
     * @param days 天数
     * @param problemId 问题ID
     * @return 趋势数据
     */
    List<Object> selectSubmissionTrend(@Param("days") Integer days,
                                      @Param("problemId") String problemId);

    /**
     * 获取通过率统计
     * 
     * @param categoryId 分类ID
     * @param difficulty 难度等级
     * @return 通过率统计
     */
    List<Object> selectAcceptanceRateStatistics(@Param("categoryId") String categoryId,
                                               @Param("difficulty") Integer difficulty);

    /**
     * 获取排行榜数据
     * 
     * @param type 排行榜类型
     * @param limit 限制数量
     * @return 排行榜数据
     */
    List<Object> selectLeaderboard(@Param("type") String type,
                                  @Param("limit") Integer limit);

    /**
     * 获取用户活跃度统计
     * 
     * @param userId 用户ID
     * @param days 天数
     * @return 活跃度统计
     */
    Object selectUserActivityStatistics(@Param("userId") String userId,
                                       @Param("days") Integer days);

    /**
     * 获取用户学习进度
     * 
     * @param userId 用户ID
     * @param categoryId 分类ID
     * @return 学习进度
     */
    Object selectUserLearningProgress(@Param("userId") String userId,
                                     @Param("categoryId") String categoryId);

    /**
     * 获取用户能力雷达图数据
     * 
     * @param userId 用户ID
     * @return 雷达图数据
     */
    Object selectUserAbilityRadar(@Param("userId") String userId);

    /**
     * 获取用户成长曲线数据
     * 
     * @param userId 用户ID
     * @param days 天数
     * @return 成长曲线数据
     */
    Object selectUserGrowthCurve(@Param("userId") String userId,
                                @Param("days") Integer days);

    /**
     * 获取全局统计信息
     * 
     * @return 全局统计
     */
    Object selectGlobalStatistics();

    /**
     * 更新问题热度分数
     * 
     * @param problemId 问题ID
     * @param hotScore 热度分数
     * @return 更新行数
     */
    int updateHotScore(@Param("problemId") String problemId,
                      @Param("hotScore") Double hotScore);

    /**
     * 批量更新问题统计
     *
     * @param statisticsList 统计数据列表
     * @return 更新行数
     */
    int batchUpdateStatistics(@Param("list") List<Object> statisticsList);

    /**
     * 问题统计信息
     */
    class ProblemStatistics {
        private Long totalProblems;
        private Long easyProblems;
        private Long mediumProblems;
        private Long hardProblems;
        private Long expertProblems;
        private Double avgAcceptRate;
        private String mostPopularTag;
        private String mostDifficultProblem;

        // Getters and Setters
        public Long getTotalProblems() { return totalProblems; }
        public void setTotalProblems(Long totalProblems) { this.totalProblems = totalProblems; }

        public Long getEasyProblems() { return easyProblems; }
        public void setEasyProblems(Long easyProblems) { this.easyProblems = easyProblems; }

        public Long getMediumProblems() { return mediumProblems; }
        public void setMediumProblems(Long mediumProblems) { this.mediumProblems = mediumProblems; }

        public Long getHardProblems() { return hardProblems; }
        public void setHardProblems(Long hardProblems) { this.hardProblems = hardProblems; }

        public Long getExpertProblems() { return expertProblems; }
        public void setExpertProblems(Long expertProblems) { this.expertProblems = expertProblems; }

        public Double getAvgAcceptRate() { return avgAcceptRate; }
        public void setAvgAcceptRate(Double avgAcceptRate) { this.avgAcceptRate = avgAcceptRate; }

        public String getMostPopularTag() { return mostPopularTag; }
        public void setMostPopularTag(String mostPopularTag) { this.mostPopularTag = mostPopularTag; }

        public String getMostDifficultProblem() { return mostDifficultProblem; }
        public void setMostDifficultProblem(String mostDifficultProblem) { this.mostDifficultProblem = mostDifficultProblem; }
    }

    /**
     * 标签统计信息
     */
    class TagStatistics {
        private String tag;
        private Long count;
        private Double avgDifficulty;
        private Double avgAcceptRate;

        // Getters and Setters
        public String getTag() { return tag; }
        public void setTag(String tag) { this.tag = tag; }

        public Long getCount() { return count; }
        public void setCount(Long count) { this.count = count; }

        public Double getAvgDifficulty() { return avgDifficulty; }
        public void setAvgDifficulty(Double avgDifficulty) { this.avgDifficulty = avgDifficulty; }

        public Double getAvgAcceptRate() { return avgAcceptRate; }
        public void setAvgAcceptRate(Double avgAcceptRate) { this.avgAcceptRate = avgAcceptRate; }
    }

    /**
     * 用户解题统计
     */
    class UserSolveStatistics {
        private String userId;
        private Long totalSolved;
        private Long easySolved;
        private Long mediumSolved;
        private Long hardSolved;
        private Long expertSolved;
        private Long totalSubmissions;
        private Double acceptRate;
        private Integer ranking;
        private Integer totalPoints;

        // Getters and Setters
        public String getUserId() { return userId; }
        public void setUserId(String userId) { this.userId = userId; }

        public Long getTotalSolved() { return totalSolved; }
        public void setTotalSolved(Long totalSolved) { this.totalSolved = totalSolved; }

        public Long getEasySolved() { return easySolved; }
        public void setEasySolved(Long easySolved) { this.easySolved = easySolved; }

        public Long getMediumSolved() { return mediumSolved; }
        public void setMediumSolved(Long mediumSolved) { this.mediumSolved = mediumSolved; }

        public Long getHardSolved() { return hardSolved; }
        public void setHardSolved(Long hardSolved) { this.hardSolved = hardSolved; }

        public Long getExpertSolved() { return expertSolved; }
        public void setExpertSolved(Long expertSolved) { this.expertSolved = expertSolved; }

        public Long getTotalSubmissions() { return totalSubmissions; }
        public void setTotalSubmissions(Long totalSubmissions) { this.totalSubmissions = totalSubmissions; }

        public Double getAcceptRate() { return acceptRate; }
        public void setAcceptRate(Double acceptRate) { this.acceptRate = acceptRate; }

        public Integer getRanking() { return ranking; }
        public void setRanking(Integer ranking) { this.ranking = ranking; }

        public Integer getTotalPoints() { return totalPoints; }
        public void setTotalPoints(Integer totalPoints) { this.totalPoints = totalPoints; }
    }
}
